package com.boost.cipher.utils;

/**
 * Created by zhou01.zhao on 2016/8/1.
 *
 * 解析PEM格式的秘钥
 */

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class PemRSAParser {

	public static final String BEGIN_PUB_KEY = "-----BEGIN PUBLIC KEY-----";
	public static final String END_PUB_KEY = "-----END PUBLIC KEY-----";

	public static final String BEGIN_RSA_PRI_KEY = "-----BEGIN RSA PRIVATE KEY-----";
	public static final String END_RSA_PRI_KEY = "-----END RSA PRIVATE KEY-----";

	public static final String BEGIN_PRI_KEY = "-----BEGIN PRIVATE KEY-----";
	public static final String END_PRI_KEY = "-----END PRIVATE KEY-----";


	private static final Logger LOG = LoggerFactory.getLogger(PemRSAParser.class);
	public static String readKeyFromFile(File file) throws Exception {
		String strKeyPEM = "";
		BufferedReader br = null;
		String line;
		try {
			br = new BufferedReader(new FileReader(file));
			while ((line = br.readLine()) != null) {
				strKeyPEM += line;
			}
		} catch (Exception e) {
			throw  e;
		} finally {
			try {
				if (br != null) {
					br.close();
				}
			} catch (IOException e) {
				throw e;
			}
		}

		strKeyPEM = strKeyPEM.replace(BEGIN_RSA_PRI_KEY, "");
		strKeyPEM = strKeyPEM.replace(BEGIN_PRI_KEY, "");
		strKeyPEM = strKeyPEM.replace(END_RSA_PRI_KEY, "");
		strKeyPEM = strKeyPEM.replace(END_PRI_KEY, "");
		strKeyPEM = strKeyPEM.replace(BEGIN_PUB_KEY, "");
		strKeyPEM = strKeyPEM.replace(END_PUB_KEY, "");
		return strKeyPEM;
	}


	public static RSAPrivateKey getPrivateKey(String filename) throws Exception {
		String privateKeyPEM = readKeyFromFile(new File(filename));
		return getPrivateKeyFromString(privateKeyPEM);
	}

	public static RSAPrivateKey getPrivateKeyFromString(String key) throws Exception {
		String privateKeyPEM = key;
		privateKeyPEM = privateKeyPEM.replace(BEGIN_RSA_PRI_KEY, "");
		privateKeyPEM = privateKeyPEM.replace(BEGIN_PRI_KEY, "");
		privateKeyPEM = privateKeyPEM.replace(END_RSA_PRI_KEY, "");
		privateKeyPEM = privateKeyPEM.replace(END_PRI_KEY, "");
		privateKeyPEM = privateKeyPEM.replace("\n", "");
		byte[] decoded = new byte[0];

		RSAPrivateKey privKey = null;
		try {
			decoded = Base64.decodeBase64(privateKeyPEM);
			KeyFactory kf = KeyFactory.getInstance("RSA");
			PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded);
			privKey = (RSAPrivateKey) kf.generatePrivate(keySpec);
		} catch (Exception e) {
			throw e;
		}
		return privKey;
	}


	public static RSAPublicKey getPublicKey(String filename) throws Exception {
		String publicKeyPEM = readKeyFromFile(new File(filename));
		return getPublicKeyFromString(publicKeyPEM);
	}

	public static RSAPublicKey getPublicKeyFromString(String key) throws Exception {
		String publicKeyPEM = key;
		publicKeyPEM = publicKeyPEM.replace(BEGIN_PUB_KEY, "");
		publicKeyPEM = publicKeyPEM.replace(END_PUB_KEY, "");
		publicKeyPEM = publicKeyPEM.replace("\n", "");
		byte[] decoded = new byte[0];
		KeyFactory kf = null;
		RSAPublicKey pubKey = null;
		try {
			decoded = Base64.decodeBase64(publicKeyPEM);
			kf = KeyFactory.getInstance("RSA");
			X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decoded);
			pubKey = (RSAPublicKey) kf.generatePublic(new X509EncodedKeySpec(decoded));
		}catch (Exception e) {
			throw e;
		}
		return pubKey;
	}

}

